package main

import (
	"fmt"
	"os"
	"strings"

	"gitee.com/libbylg/pkgr/repo"
)

type CmdMergeOptions struct {
	PlanFiles  []string
	OutputPlan string
}

// NewCmdQueryOptions 识别命令行选项.
// pkgr merge PlanFiles...
func NewCmdMergeOptions(argv []string) (*CmdMergeOptions, error) {
	// 检查参数数量
	if len(argv) < 3 {
		return nil, fmt.Errorf("the required parameter is missing, try -h for help")
	}

	// 初始化默认值
	opt := &CmdMergeOptions{
		PlanFiles:  make([]string, 0, len(argv)),
		OutputPlan: "",
	}

	pos := 0

	// 读取选项
	for index := 2; index < len(argv); index++ {
		if argv[index] == "-o" {
			if index+1 >= len(argv) {
				return nil, fmt.Errorf("the option `%v' is missing value", argv[index])
			}

			index++
			opt.OutputPlan = argv[index]
			continue
		}

		// 遇到无法识别的选项
		if strings.HasPrefix(argv[index], "-") {
			return nil, fmt.Errorf("unsupported options `%v'", argv[index])
		}

		// 识别 PlanFiles... 参数
		opt.PlanFiles = append(opt.PlanFiles, argv[index])
		pos++
		continue
	}

	if len(opt.PlanFiles) == 0 {
		return nil, fmt.Errorf("the required parameter `PLAN-FILE...' is missing, try -h for help")
	}

	return opt, nil
}

// CmdMerge 合并多个 conf 文件
// pkgr merge PlanFile...
func CmdMerge(argv []string) int {
	if len(argv) < 3 {
		ERROR("Missing parameter, try -h for help")
		return 1
	}

	// 加载选项
	opt, err := NewCmdMergeOptions(argv)
	if err != nil {
		ERROR("Load option for `%v' failed: %v", "list", err.Error())
		return 1
	}

	sumPlan := repo.NewInstallPlan(100)
	for index := 0; index < len(opt.PlanFiles); index++ {
		plan, err := repo.ReadInstallPlanFile(opt.PlanFiles[index], true)
		if err != nil {
			ERROR("Load install plan file failed: %v", err.Error())
			return 1
		}

		plan.Enumerate(func(index int, item *repo.InstallPlanItem) bool {
			sumPlan.Merge(item)
			return true
		})
	}

	// 如果没有指定文件直接输出到控制台
	err = repo.WriteInstallPlan(sumPlan, os.Stdout)
	if err != nil {
		ERROR("Write merged result to install plan file failed: %v", err.Error())
		return 1
	}

	return 0
}
